#include "common.h"
#include "linux/sched.h"
#include "sys/stat.h"

static void free_ind(int dev,int block)
{
    struct buffer_head *bh;
    uint16_t *p;
    int i;

    if(!block)
    {
        return;
    }

    if(bh = bread(dev,block))
    {
        p = (uint16_t *)bh -> b_data;

        for(i = 0;i < (BLOCK_SIZE >> 1);i++,p++)
        {
            if(*p)
            {
                free_block(dev,*p);
            }
        }

        brelse(bh);
    }

    free_block(dev,block);
}

static void free_dind(int dev,int block)
{
    struct buffer_head *bh;
    uint16_t *p;
    int i;

    if(!block)
    {
        return;
    }

    if(bh = bread(dev,block))
    {
        p = (uint16_t *)bh -> b_data;

        for(i = 0;i < (BLOCK_SIZE >> 1);i++,p++)
        {
            if(*p)
            {
                free_ind(dev,*p);
            }
        }

        brelse(bh);
    }

    free_block(dev,block);
}

void truncate(struct m_inode *inode)
{
    int i;

    if(!(S_ISREG(inode -> i_mode)) || S_ISDIR(inode -> i_mode))
    {
        return;
    }

    for(i = 0;i < 7;i++)
    {
        if(inode -> i_zone[i])
        {
            free_block(inode -> i_dev,inode -> i_zone[i]);
            inode -> i_zone[i] = 0;
        }
    }

    free_ind(inode -> i_dev,inode -> i_zone[7]);
    free_ind(inode -> i_dev,inode -> i_zone[8]);
    inode -> i_zone[7] = inode -> i_zone[8] = 0;
    inode -> i_size = 0;
    inode -> i_dirt = 1;
    inode -> i_mtime = inode -> i_ctime = CURRENT_TIME;
}